package sagroup.dracots.policy;

import lime2.LimeTupleSpace;
import lime2.Location;
import lime2.TupleID;
import sagroup.dracots.DracoConstants;
import sagroup.dracots.DracoTS;
import sagroup.dracots.Field;
import sagroup.dracots.ShareTuple;
import sagroup.dracots.SystemTupleType;
import sagroup.dracots.TupleType;

/**
 * Replication Policy Tuple.
 * 
 * @author Huang Xiaodong
 */
public class RPTuple extends ShareTuple {
	/**
	 * 
	 */
	private static final long serialVersionUID = 6918905371968363268L;

	/**
	 * target tuple type to set policy
	 */
	@Field
	TupleType targetType;

	/**
	 * target node to set policy
	 */
	@Field
	Location targetNode;

	/**
	 * policy to set
	 */
	@Field
	ReplicationPolicy policy;


	/**
	 * the template that matches any replication policy tuple
	 */
	public static final RPTuple RP_TEMPLATE;
	static {
		RP_TEMPLATE = new RPTuple(null, Location.HERE,
				Location.HERE, null, null, Location.UNSPECIFIED,
				Location.UNSPECIFIED, null, null,
				Location.UNSPECIFIED, null);
	}
	/**
	 * the template that matches replication policy's replication policy
	 * with target of Location.HERE
	 */
	public static final RPTuple RP2_LOCAL_TEMPLATE;
	static {
		RP2_LOCAL_TEMPLATE = new RPTuple(null, Location.HERE,
				Location.HERE, null, null, Location.INVALID, Location.INVALID,
				Boolean.FALSE, SystemTupleType.REPLICATION_POLICY, Location.HERE, null);
	}

	private RPTuple(TupleID tid, Location curr, Location dest, TupleID vid,
			Long ver, Location masterCurr, Location masterDest,
			Boolean isReplica, TupleType targetType,
			Location targetNode, ReplicationPolicy policy) {
		super(tid, curr, dest, SystemTupleType.REPLICATION_POLICY, vid, ver, masterCurr,
				masterDest, isReplica);
		this.targetType = targetType;
		this.targetNode = targetNode;
		this.policy = policy;
	}

	public RPTuple(TupleType targetType, ReplicationPolicy policy) {
		this(LimeTupleSpace.nextTID(), Location.HERE, Location.HERE, DracoTS
				.nextVID(), new Long(DracoConstants.INITIAL_VER_NUM),
				Location.INVALID, Location.INVALID, new Boolean(false),
				targetType, Location.HERE, policy);
	}

	public RPTuple() {
		// empty constructor
	}

	public TupleType getTargetType() {
		return targetType;
	}

	public void setTargetType(TupleType targetType) {
		this.targetType = targetType;
	}

	public Location getTargetNode() {
		return targetNode;
	}

	public void setTargetNode(Location targetNode) {
		this.targetNode = targetNode;
	}

	public ReplicationPolicy getPolicy() {
		return policy;
	}

	public void setPolicy(ReplicationPolicy policy) {
		this.policy = policy;
	}

	@Override
	public String toString() {
		return super.toString()
				+ String.format("targetType=%s;targetNode=%s;Policy=%s",
						targetType.toString(), targetNode.toString(), policy
								.toString());
	}
}